package com.runa.protocol.dto;

import com.runa.protocol.enums.ModbusFunctionCode;
import com.runa.protocol.enums.ModbusType;
import lombok.extern.slf4j.Slf4j;

/**
 * @author zhuj
 */
@Slf4j
public class ModbusReadRequestData extends ModbusRequestData {

    private int count;

    public ModbusReadRequestData(int slaveId,
                 ModbusFunctionCode functionCode,int address, int count, ModbusType type) {
        super(slaveId, functionCode, address, type);
        this.count = count;
    }

    @Override
    public byte[] toByteArray() {
        byte[] bs = new byte[2];
        bs[0] = (byte) (count >> 8);
        bs[1] = (byte) (count & 0xff);
        return bs;
    }

    @Override
    public boolean isReadWrite() {
        return true;
    }

    @Override
    public boolean check(IResponseData data) {
        try {
            ModbusResponseData responseData = (ModbusResponseData) data;
            log.info("responseData: {} {} {} {} {}", responseData.getTransSign(), responseData.getType()
                    , responseData.getSlaveId(), responseData.getFunctionCode(), responseData.getCount());
            log.info("requestData: {} {} {} {} {}", this.getTransSign(), this.getType()
                    , this.getSlaveId(), this.getFunctionCode(), count*2);
            if (this.getTransSign() != responseData.getTransSign()) return false;

            if (responseData.getType().equals(getType()) &&
                    responseData.getSlaveId() == getSlaveId() &&
                    responseData.getFunctionCode().equals(getFunctionCode())) {
                switch (getFunctionCode()) {
                    case READ_COILS:
                    case READ_INPUTS:
                        int quo = count/8, rem = count%8;
                        return responseData.getCount() == (rem==0 ? quo : quo+1);
                    case READ_INPUT_REGISTERS:
                    case READ_HOLDING_REGISTERS:
                        return responseData.getCount() == count*2;
                }
            }
        } catch (Exception e){
            log.error("", e);
        }
        return false;
    }

}
